// 实用工具模块中文封装
const util = require('util');
const querystring = require('querystring');
const url = require('url');

/**
 * 格式化字符串
 * @param {string} 格式字符串 - 包含占位符的字符串
 * @param {...*} 参数 - 替换占位符的值
 * @returns {string} 格式化后的字符串
 */
function 格式化字符串(格式字符串, ...参数) {
  return util.format(格式字符串, ...参数);
}

/**
 * 检查值是否为指定类型
 * @param {*} 值 - 要检查的值
 * @param {Function|string} 类型 - 类型构造函数或类型名称
 * @returns {boolean} 是否为指定类型
 */
function 是类型(值, 类型) {
  return util.types.is(值, 类型);
}

/**
 * 将回调函数转换为Promise
 * @param {Function} 函数 - 要转换的回调函数
 * @returns {Function} 返回Promise的函数
 */
function 转换为Promise(函数) {
  return util.promisify(函数);
}

/**
 * 将Promise函数转换为回调函数
 * @param {Function} 函数 - 返回Promise的函数
 * @returns {Function} 回调风格的函数
 */
function 转换为回调(函数) {
  return util.callbackify(函数);
}

/**
 * 创建继承关系
 * @param {Function} 子类 - 子构造函数
 * @param {Function} 父类 - 父构造函数
 */
function 创建继承(子类, 父类) {
  util.inherits(子类, 父类);
}

/**
 * 获取对象的检查表示
 * @param {*} 对象 - 要检查的对象
 * @param {Object} 选项 - 检查选项
 * @returns {string} 对象的字符串表示
 */
function 检查对象(对象, 选项) {
  return util.inspect(对象, 选项);
}

/**
 * 检查值是否为数组
 * @param {*} 值 - 要检查的值
 * @returns {boolean} 是否为数组
 */
function 是数组(值) {
  return Array.isArray(值);
}

/**
 * 检查值是否为对象
 * @param {*} 值 - 要检查的值
 * @returns {boolean} 是否为对象（非null）
 */
function 是对象(值) {
  return 值 !== null && typeof 值 === 'object';
}

/**
 * 检查值是否为函数
 * @param {*} 值 - 要检查的值
 * @returns {boolean} 是否为函数
 */
function 是函数(值) {
  return typeof 值 === 'function';
}

/**
 * 检查值是否为字符串
 * @param {*} 值 - 要检查的值
 * @returns {boolean} 是否为字符串
 */
function 是字符串(值) {
  return typeof 值 === 'string';
}

/**
 * 检查值是否为数字
 * @param {*} 值 - 要检查的值
 * @returns {boolean} 是否为数字
 */
function 是数字(值) {
  return typeof 值 === 'number' && !isNaN(值);
}

/**
 * 检查值是否为布尔值
 * @param {*} 值 - 要检查的值
 * @returns {boolean} 是否为布尔值
 */
function 是布尔值(值) {
  return typeof 值 === 'boolean';
}

/**
 * 解析URL字符串
 * @param {string} url字符串 - 要解析的URL
 * @param {boolean} 解析查询字符串 - 是否解析查询字符串部分
 * @returns {Object} 解析后的URL对象
 */
function 解析URL(url字符串, 解析查询字符串 = false) {
  return url.parse(url字符串, 解析查询字符串);
}

/**
 * 格式化URL对象为字符串
 * @param {Object} url对象 - URL对象
 * @returns {string} 格式化后的URL字符串
 */
function 格式化URL(url对象) {
  return url.format(url对象);
}

/**
 * 解析查询字符串
 * @param {string} 查询字符串 - URL查询字符串部分
 * @returns {Object} 解析后的查询参数对象
 */
function 解析查询字符串(查询字符串) {
  return querystring.parse(查询字符串);
}

/**
 * 将对象转换为查询字符串
 * @param {Object} 对象 - 要转换的对象
 * @returns {string} 转换后的查询字符串
 */
function 对象转查询字符串(对象) {
  return querystring.stringify(对象);
}

/**
 * 深度复制对象
 * @param {Object} 对象 - 要复制的对象
 * @returns {Object} 复制后的新对象
 */
function 深度复制(对象) {
  if (对象 === null || typeof 对象 !== 'object') {
    return 对象;
  }
  if (对象 instanceof Date) {
    return new Date(对象.getTime());
  }
  if (对象 instanceof Array) {
    return 对象.map(item => 深度复制(item));
  }
  const 新对象 = {};
  for (const 键 in 对象) {
    if (对象.hasOwnProperty(键)) {
      新对象[键] = 深度复制(对象[键]);
    }
  }
  return 新对象;
}

/**
 * 延迟执行
 * @param {number} 毫秒 - 延迟的毫秒数
 * @returns {Promise} 延迟后的Promise
 */
function 延迟(毫秒) {
  return new Promise(resolve => setTimeout(resolve, 毫秒));
}

/**
 * 重试函数执行
 * @param {Function} 函数 - 要重试的函数
 * @param {number} 最大尝试次数 - 最大重试次数
 * @param {number} 延迟毫秒 - 重试间隔
 * @returns {Promise} 执行结果的Promise
 */
async function 重试(函数, 最大尝试次数 = 3, 延迟毫秒 = 1000) {
  let 尝试次数 = 0;
  
  while (true) {
    try {
      return await 函数();
    } catch (错误) {
      尝试次数++;
      if (尝试次数 >= 最大尝试次数) {
        throw 错误;
      }
      await 延迟(延迟毫秒);
    }
  }
}

module.exports = {
  格式化字符串,
  是类型,
  转换为Promise,
  转换为回调,
  创建继承,
  检查对象,
  是数组,
  是对象,
  是函数,
  是字符串,
  是数字,
  是布尔值,
  解析URL,
  格式化URL,
  解析查询字符串,
  对象转查询字符串,
  深度复制,
  延迟,
  重试
};